import { Provide, Inject, Init } from '@midwayjs/core';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { AutomationPipelineEntity } from '../../entity/pipeline';
import { AutomationConditionEntity } from '../../entity/condition';
import { AutomationTaskEntity } from '../../entity/task';
import { IotWeatherDataEntity } from '../../entity/weather_data';
import { IotDeviceStatusEntity } from '../../entity/device_status';

/**
 * 自动化执行引擎
 */
@Provide()
export class AutomationEngineService extends BaseService {
  @InjectEntityModel(AutomationPipelineEntity)
  automationPipelineEntity: Repository<AutomationPipelineEntity>;

  @InjectEntityModel(AutomationConditionEntity)
  automationConditionEntity: Repository<AutomationConditionEntity>;

  @InjectEntityModel(AutomationTaskEntity)
  automationTaskEntity: Repository<AutomationTaskEntity>;

  @InjectEntityModel(IotWeatherDataEntity)
  automationWeatherDataEntity: Repository<IotWeatherDataEntity>;

  @InjectEntityModel(IotDeviceStatusEntity)
  automationDeviceStatusEntity: Repository<IotDeviceStatusEntity>;

  private runningPipelines: Map<number, any> = new Map();

  @Init()
  async init() {
    // 启动时加载所有启用的流水线
    await this.loadActivePipelines();
  }

  /**
   * 加载所有启用的流水线
   */
  async loadActivePipelines() {
    const pipelines = await this.automationPipelineEntity.find({
      where: { status: 1 },
    });

    for (const pipeline of pipelines) {
      await this.startPipelineMonitoring(pipeline.id);
    }
  }

  /**
   * 启动流水线监控
   */
  async startPipelineMonitoring(pipelineId: number) {
    const pipeline = await this.automationPipelineEntity.findOneBy({
      id: pipelineId,
    });
    if (!pipeline || pipeline.status !== 1) {
      return;
    }

    const conditions = await this.automationConditionEntity.find({
      where: { pipelineId },
    });

    if (conditions.length === 0) {
      return;
    }

    // 设置监控间隔（每30秒检查一次）
    const interval = setInterval(async () => {
      try {
        await this.checkPipelineConditions(pipelineId);
      } catch (error) {
        console.error(`Pipeline ${pipelineId} monitoring error:`, error);
      }
    }, 30000);

    this.runningPipelines.set(pipelineId, { interval, pipeline });
  }

  /**
   * 停止流水线监控
   */
  async stopPipelineMonitoring(pipelineId: number) {
    const monitoring = this.runningPipelines.get(pipelineId);
    if (monitoring) {
      clearInterval(monitoring.interval);
      this.runningPipelines.delete(pipelineId);
    }
  }

  /**
   * 检查流水线条件
   */
  async checkPipelineConditions(pipelineId: number) {
    const pipeline = await this.automationPipelineEntity.findOneBy({
      id: pipelineId,
    });
    if (!pipeline || pipeline.status !== 1) {
      return;
    }

    // 检查生效时间段
    if (!this.isInEffectTime(pipeline)) {
      return;
    }

    const conditions = await this.automationConditionEntity.find({
      where: { pipelineId },
    });

    if (conditions.length === 0) {
      return;
    }

    const conditionResults = [];
    for (const condition of conditions) {
      const result = await this.checkSingleCondition(condition);
      conditionResults.push(result);
    }

    // 根据条件关系判断是否触发
    let shouldTrigger = false;
    if (pipeline.conditionRelation === 0) {
      // 满足全部条件
      shouldTrigger = conditionResults.every(result => result);
    } else {
      // 满足任一条件
      shouldTrigger = conditionResults.some(result => result);
    }

    if (shouldTrigger) {
      await this.executePipelineTasks(pipelineId, pipeline.delayTime);
    }
  }

  /**
   * 检查单个条件
   */
  async checkSingleCondition(
    condition: AutomationConditionEntity
  ): Promise<boolean> {
    switch (condition.conditionType) {
      case 0: // 气象条件
        return await this.checkWeatherCondition(condition);
      case 1: // 设备条件
        return await this.checkDeviceCondition(condition);
      case 2: // 定时条件
        return this.checkTimeCondition(condition);
      default:
        return false;
    }
  }

  /**
   * 检查气象条件
   */
  async checkWeatherCondition(
    condition: AutomationConditionEntity
  ): Promise<boolean> {
    if (!condition.cityCode) {
      return false;
    }

    const weatherData = await this.automationWeatherDataEntity.findOne({
      where: { cityCode: condition.cityCode },
      order: { collectTime: 'DESC' },
    });

    if (!weatherData) {
      return false;
    }

    let actualValue: any;
    switch (condition.weatherType) {
      case 0: // 温度
        actualValue = weatherData.temperature;
        break;
      case 1: // 湿度
        actualValue = weatherData.humidity;
        break;
      case 2: // 天气
        actualValue = weatherData.weather;
        break;
      case 3: // PM2.5
        actualValue = weatherData.pm25;
        break;
      case 4: // 空气质量
        actualValue = weatherData.aqi;
        break;
      case 5: // 日落日出
        const now = new Date();
        const currentTime = now.getHours() * 60 + now.getMinutes();
        const sunriseTime = this.timeStringToMinutes(weatherData.sunrise);
        const sunsetTime = this.timeStringToMinutes(weatherData.sunset);
        actualValue = currentTime;
        break;
      case 6: // 风速
        actualValue = weatherData.windSpeed;
        break;
      default:
        return false;
    }

    return this.compareValues(
      actualValue,
      condition.threshold,
      condition.compareType
    );
  }

  /**
   * 检查设备条件
   */
  async checkDeviceCondition(
    condition: AutomationConditionEntity
  ): Promise<boolean> {
    if (!condition.deviceId) {
      return false;
    }

    const deviceStatus = await this.automationDeviceStatusEntity.findOne({
      where: { deviceId: condition.deviceId },
      order: { reportTime: 'DESC' },
    });

    if (!deviceStatus) {
      return false;
    }

    let actualValue: any;
    try {
      const statusData = JSON.parse(deviceStatus.status);
      actualValue = condition.deviceField
        ? statusData[condition.deviceField]
        : statusData;
    } catch {
      actualValue = deviceStatus.status;
    }

    return this.compareValues(
      actualValue,
      condition.threshold,
      condition.compareType
    );
  }

  /**
   * 检查定时条件
   */
  checkTimeCondition(condition: AutomationConditionEntity): boolean {
    if (!condition.triggerTime) {
      return false;
    }

    const now = new Date();
    const currentTime = `${now.getHours().toString().padStart(2, '0')}:${now
      .getMinutes()
      .toString()
      .padStart(2, '0')}`;

    return currentTime === condition.triggerTime;
  }

  /**
   * 比较值
   */
  compareValues(
    actualValue: any,
    threshold: string,
    compareType: number
  ): boolean {
    const thresholdValue = isNaN(Number(threshold))
      ? threshold
      : Number(threshold);
    const actual = isNaN(Number(actualValue))
      ? actualValue
      : Number(actualValue);

    switch (compareType) {
      case 0: // 大于
        return actual > thresholdValue;
      case 1: // 小于
        return actual < thresholdValue;
      case 2: // 等于
        return actual === thresholdValue;
      case 3: // 不等于
        return actual !== thresholdValue;
      case 4: // 大于等于
        return actual >= thresholdValue;
      case 5: // 小于等于
        return actual <= thresholdValue;
      default:
        return false;
    }
  }

  /**
   * 检查是否在生效时间段内
   */
  isInEffectTime(pipeline: AutomationPipelineEntity): boolean {
    if (!pipeline.effectStartTime || !pipeline.effectEndTime) {
      return true; // 没有设置时间限制，默认生效
    }

    const now = new Date();
    const currentTime = now.getHours() * 60 + now.getMinutes();
    const startTime = this.timeStringToMinutes(pipeline.effectStartTime);
    const endTime = this.timeStringToMinutes(pipeline.effectEndTime);

    // 检查时间段
    const timeInRange = startTime <= currentTime && currentTime <= endTime;
    if (!timeInRange) {
      return false;
    }

    // 检查日期类型
    const dayOfWeek = now.getDay(); // 0=周日, 1=周一, ..., 6=周六
    switch (pipeline.effectDateType) {
      case 0: // 每天
        return true;
      case 1: // 工作日 (周一到周五)
        return dayOfWeek >= 1 && dayOfWeek <= 5;
      case 2: // 周末 (周六和周日)
        return dayOfWeek === 0 || dayOfWeek === 6;
      case 3: // 自定义
        if (pipeline.effectDates) {
          try {
            const customDates = JSON.parse(pipeline.effectDates);
            return customDates.includes(dayOfWeek);
          } catch {
            return true;
          }
        }
        return true;
      default:
        return true;
    }
  }

  /**
   * 时间字符串转分钟数
   */
  timeStringToMinutes(timeStr: string): number {
    if (!timeStr) return 0;
    const [hours, minutes] = timeStr.split(':').map(Number);
    return hours * 60 + minutes;
  }

  /**
   * 执行流水线任务
   */
  async executePipelineTasks(pipelineId: number, delayTime: number = 0) {
    const tasks = await this.automationTaskEntity.find({
      where: { pipelineId },
      order: { order: 'ASC' },
    });

    if (tasks.length === 0) {
      return;
    }

    // 延时执行
    if (delayTime > 0) {
      setTimeout(async () => {
        await this.executeTaskList(tasks);
      }, delayTime * 1000);
    } else {
      await this.executeTaskList(tasks);
    }
  }

  /**
   * 执行任务列表
   */
  async executeTaskList(tasks: AutomationTaskEntity[]) {
    for (const task of tasks) {
      try {
        await this.executeSingleTask(task);
        // 任务间隔1秒
        await new Promise(resolve => setTimeout(resolve, 1000));
      } catch (error) {
        console.error(`Task execution error:`, error);
      }
    }
  }

  /**
   * 执行单个任务
   */
  async executeSingleTask(task: AutomationTaskEntity) {
    // 这里需要根据实际的设备控制接口来实现
    // 示例实现：
    console.log(`Executing task for device ${task.deviceId}:`);
    console.log(
      `Action: ${task.actionType}, Field: ${task.deviceField}, Value: ${task.setValue}`
    );

    // TODO: 调用实际的设备控制接口
    // await this.deviceControlService.controlDevice({
    //   deviceId: task.deviceId,
    //   actionType: task.actionType,
    //   field: task.deviceField,
    //   value: task.setValue,
    //   command: task.command
    // });
  }

  /**
   * 重新加载流水线
   */
  async reloadPipeline(pipelineId: number) {
    await this.stopPipelineMonitoring(pipelineId);
    await this.startPipelineMonitoring(pipelineId);
  }

  /**
   * 手动触发流水线
   */
  async triggerPipeline(pipelineId: number) {
    const pipeline = await this.automationPipelineEntity.findOneBy({
      id: pipelineId,
    });
    if (pipeline) {
      await this.executePipelineTasks(pipelineId, 0);
    }
  }

  /**
   * 启动自动化引擎
   */
  async startEngine() {
    console.log('正在启动自动化引擎...');

    // 加载所有启用的流水线
    const enabledPipelines = await this.automationPipelineEntity.find({
      where: { status: 1 }, // 启用状态
    });

    console.log(`发现 ${enabledPipelines.length} 个启用的流水线`);

    // 启动每个流水线的监控
    for (const pipeline of enabledPipelines) {
      await this.startPipelineMonitoring(pipeline.id);
    }

    console.log('自动化引擎启动完成');
  }

  /**
   * 停止自动化引擎
   */
  async stopEngine() {
    console.log('正在停止自动化引擎...');

     
    console.log('自动化引擎已停止');
  }

  /**
   * 重启自动化引擎
   */
  async restartEngine() {
    await this.stopEngine();
    await this.startEngine();
  }
}
